算法的個人認知分享

       一提到算法,或許很多人覺得高大上,覺得很複雜。其實算法就是能利用特定方法使得現實問題更加簡便的去解決的方法。同一問題的解決,可以有不同的算法完成,算法本身可簡便,也可複雜。算法在大部分程序中有着舉足輕重的作用。數據結構用來存儲實際業務的運算結果,算法用來解決實際應用場景的數據處理過程,實際上編碼的本質就是數據結構和算法的搭配。

        正如Pascal之父所言,如果說有一個人因爲一句話而得到了圖靈獎,那麼這個人應該就是NicklausWirth,這句話就是他提出的著名公式“算法+數據結構=程序”。

        我個人工作這7年多所接觸的算法,大都來自於金融量化、策略交易、通信、圖像處理和模式識別領域,其他的沒有接觸過,不敢多做評價。做算法前,首當其衝的是先要做算法準備:舉個例子,在做視頻的算法時,肯定免不了視頻的解碼,拿到一幅圖像,甚至到了拿到一個像素,纔是開始算法本身的工作。而這些工作,對於專注於某個算法的人來說,應該是透明的。而且我相信能獨立的編寫出從讀取視頻到獲取像素的全部程序的人也不是很多。

       國內很多院校研究所,科研機構,喜歡使用matlab。因爲matlab提供了強大的函數庫,使得複雜的數學運算(尤其是矩陣運算(奇異值分解、插值等等))、圖像處理、模式識別等基本算法能夠通過函數調用來完成,使得自己能夠專注於問題,提出改進的思路。而且對於圖像、視頻,提供的讀寫函數自動完成了編解碼操作,讓我們可以專注於算法本身。但是缺點就是速度慢,對於實時性驗證的場合不太適合。也有很多用C寫算法的。算法無非就是一個解決問題的辦法,輸入、輸出,使用函數來描述剛剛好。而且,一般對於算法的描述,也是按步驟進行的,與面向過程的思想是相符的。加上C語言較高的執行效率,的確是一種不錯的選擇。而且,現在有很多庫也可以供大家使用,能讓程序員專注於解決問題。但是,算法本身也有一些特點,比如參數很多,導致函數的聲明非常長。有時我不得不將一些參數、數據結構設爲全局變量,要不然難以完成遞歸的操作。而全局變量使用太多也不是什麼好事。

      那麼什麼樣的算法算是好的算法呢?

      就我個人愚見,大概可以總結爲下面幾條:

1、算法的正確性

      即對於任意的一組輸入,包括合理的輸入與不合理的輸入,總能得到預期的輸出。如果一個算法只是對合理的輸入才能得到預期的輸出,而在異常情況下卻無法預料輸出的結果,那麼它就不是正確的,算法至少應該具有輸入、輸出和加工處理無歧義性、 能正確反映問題的需求、能夠得到問題的正確答案。具體可以體現在以下兩個方面:

      (1).算法程序沒有語法錯誤,算法程序對於合法的輸入數據能夠產生滿足要求的輸出結果。

      (2).算法程序對於非法的輸入數據能夠得出滿足規格說明的結果。

                                       

2、算法的可讀性和確定性

     算法必須是由一系列具體步驟組成的,並且每一步都能夠被計算機所理解和執行,而不是抽象和模糊的概念。可讀性是算法好壞一個重要的判斷標準,當然有可能兩種算法都可以完成一種功能,一個可能十幾行代碼可以巧妙的實現,另外一個則可能需要幾百行代碼,那麼哪個更好呢?還需要看可讀性,巧妙簡潔實現的,可能很難讀懂,但是另外一個雖然代碼長了點,但是便於理解閱讀。那麼很可能大家更傾向於接受第二種算法。

3、算法的健壯性

       這一點非常重要,一個好的算法還應該能對輸入數據不合法的情況做合適的處理。比如輸入的時間或者距離不應該是負數等。當實際輸入數據不合法時,算法也能做出相關處理,而不是產生異常或莫名其妙的結果。

4、高效性

     在實際工程項目中,算法高效性是非常重要的,高效的算法能給客戶更好的體驗度,這一點非常重要,例如,我們做量化交易,1秒幾百萬,幾億的交易那是再正常不過了,時間就是金錢,0.1ms的延遲,可能導致很大的損失,甚至交易失敗。不同的軟件在這方面的差異性還是蠻大的。

                           

       那麼,使用C++來寫算法有什麼好處呢?

       其實C++本來就是C語言衍生過來的,基本上繼承了C的所有良好特性,快速高效,但是又比C語言功能強大太多,可以認爲C++由面向過程的C語言,面向對象的繼承、封裝、多態、STL庫、泛型編程、C11的智能指針、自動類型推導、正則表達式等新屬性。雖然掌握起來本身就不是很容易,用它寫算法似乎更難。但是我覺得算法本質上是基於過程的、有具體步驟的,所以我不太傾向於在具體的算法之間使用繼承派生關係,更多的時候,只是將算法與算法所操作的數據進行封裝,這更像是一種基於對象的思路(帶類的C語言)。而泛型編程在算法中的使用可能也不是很廣泛吧,特定算法要處理的數據類型往往是確定的,不太可能出現“泛型”問題。而STL庫更是大大降低了算法實現的複雜度,對於需要依賴於一些數據結構的算法,STL提供了這些結構的模板;對於算法中的查找、排序等操作,STL庫提供了高效的函數可以調用。最主要的是,STL提供了統一的泛型接口,是得他掌握起來非常容易。根據面向對象的思想,我們可以把同類算法抽象合併,極大的減少了編寫代碼的工作量,而且使得代碼更加容易維護。比如我編寫過一個在視頻中檢測運動目標的程序,我是將控制視頻的操作,比如起始幀、結束幀,依次讀取每一幅圖像等封裝成了一個類,而將算法本身需要的數據結構、閾值等封裝成了另一個類,甚至,對於每個像素需要的數據結構,進行了封裝。這樣當我們需要對算法進行修改時就非常方便了。而且由於STL庫的存在,是得一些簡單的問題,比如鏈表、隊列、排序等等可以通過函數來完成而又不失高效。

        國內的企業,除了一些大型的企業外,一般很少有的算法團隊,大部分科研院所都是使用matlab進行仿真。但是真正使用算法到實際應用中。C++應該是個不錯的選擇!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章